/**
 * 
 */
package org.mspring.mlog.service.search.impl;

import java.io.Serializable;
import java.util.List;

import org.apache.lucene.search.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.search.FullTextQuery;
import org.hibernate.search.FullTextSession;
import org.hibernate.search.MassIndexer;
import org.hibernate.search.Search;
import org.hibernate.search.query.dsl.QueryBuilder;
import org.mspring.platform.persistence.hibernate.HibernateUtils;
import org.mspring.platform.persistence.support.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * 
 * @author Gao Youbo
 * @since 2013-7-6
 */
@Service
@SuppressWarnings({ "rawtypes", "unchecked" })
public class HibernateSearchTemplate {
    @Autowired
    private SessionFactory sessionFactory;

    private Session getSession() {
        return HibernateUtils.getSession(sessionFactory);
    }

    public static final int DEFAULT_BATCH_SIZE = 100;

    public FullTextSession getFullTextSession() {
        return Search.getFullTextSession(getSession());
    }

    public void updateIndex(Class clazz, Serializable id) {
        Session session = getSession();
        Object object = session.get(clazz, id);
        Search.getFullTextSession(session).index(object);
    }

    public void updateAllIndex(Class clazz) {
        updateAllIndex(clazz, DEFAULT_BATCH_SIZE);
    }

    public void updateAllIndex(Class clazz, int batchSize) {
        MassIndexer indexer = Search.getFullTextSession(getSession()).createIndexer(clazz);
        indexer.batchSizeToLoadObjects(batchSize);
        indexer.start();
    }

    public Page listPage(Class entityClass, Page page, String text, String... fields) {
        FullTextSession fullTextSession = getFullTextSession();
        QueryBuilder queryBuilder = fullTextSession.getSearchFactory().buildQueryBuilder().forEntity(entityClass).get();

        Query query = queryBuilder.keyword().onFields(fields).matching(text).createQuery();

        FullTextQuery fullTextQuery = fullTextSession.createFullTextQuery(query, entityClass);

        if (page.isAutoCount()) {
            page.setTotalCount(fullTextQuery.getResultSize());
            page.setAutoCount(false);
        }
        fullTextQuery.setFirstResult(page.getFirst() - 1);
        fullTextQuery.setMaxResults(page.getPageSize());

        List<?> result = fullTextQuery.list();

        page.setResult(result);
        return page;
    }
}
